﻿//
// (C) Copyright 2009 Irantha Suwandarathna (irantha@gmail.com)
// All rights reserved.
//

using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using EffiProz.Core;
using EffiProz.Core.Lib;
using EffiProz.Core.Persist;
using System.Threading;


namespace EffiProz.Test.SelfTest
{
    /// <summary>
    /// Summary description for TestPersistence
    /// </summary>
    [TestClass]
    public class TestPersistence : BaseTest
    {
       
        string testScriptPath = "../../../Test/SelfTest/Scripts/";
        

        public TestPersistence()
        {      
          
        }
      

        private TestContext testContextInstance;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #region Additional test attributes
        //
        // You can use the following additional attributes as you write your tests:
        //
        // Use ClassInitialize to run code before running the first test in the class
        // [ClassInitialize()]
        // public static void MyClassInitialize(TestContext testContext) { }
        //
        // Use ClassCleanup to run code after all tests in a class have run
        // [ClassCleanup()]
        // public static void MyClassCleanup() { }
        //
        // Use TestInitialize to run code before running each test 
        // [TestInitialize()]
        // public void MyTestInitialize() { }
        //
        // Use TestCleanup to run code after each test has run
        // [TestCleanup()]
        // public void MyTestCleanup() { }
        //
        #endregion

        [TestMethod]
        public void TestSelfSchemaPersistA()
        {
            CleanUp("PersistA");
            SessionInterface sessionProxy1 = ConnectToFileDB("PersistA");
            string scriptPath = testScriptPath + "TestSelfSchemaPersistA1.txt";
            TestUtil.testScript(sessionProxy1, scriptPath);
            sessionProxy1.close();

            Thread.Sleep(1000);

            SessionInterface sessionProxy2 = ConnectToFileDB("PersistA");
            scriptPath = testScriptPath + "TestSelfSchemaPersistA2.txt";
            TestUtil.testScript(sessionProxy2, scriptPath);
        }

        [TestMethod]
        public void TestCreateSampleDB()
        {
            CleanUp("SampleDB");
            SessionInterface sessionProxy1 = ConnectToFileDB("SampleDB");
            string scriptPath = testScriptPath + "SampleDB.txt";
            TestUtil.testScript(sessionProxy1, scriptPath);
            sessionProxy1.close();           
        }

        [TestMethod]
        public void TestSelfSchemaPersistA_MVCC()
        {
            CleanUp("PersistA_MVCC");
            EffiProzProperties props = new EffiProzProperties();
            props.setProperty(EffiProz.Core.Persist.EffiProzDatabaseProperties.effiproz_tx, "MVCC");
            SessionInterface sessionProxy1 = ConnectToFileDB("PersistA_MVCC",props);
            string scriptPath = testScriptPath + "TestSelfSchemaPersistA1.txt";
            TestUtil.testScript(sessionProxy1, scriptPath);
            sessionProxy1.close();

            Thread.Sleep(1000);

            SessionInterface sessionProxy2 = ConnectToFileDB("PersistA_MVCC", props);
            scriptPath = testScriptPath + "TestSelfSchemaPersistA2.txt";
            TestUtil.testScript(sessionProxy2, scriptPath);
        }

        [TestMethod]
        public void TestSelfSchemaPersistA_MVLOCKS()
        {
            CleanUp("PersistA_MVLOCKS");
            EffiProzProperties props = new EffiProzProperties();
            props.setProperty(EffiProz.Core.Persist.EffiProzDatabaseProperties.effiproz_tx, "MVLOCKS");
            SessionInterface sessionProxy1 = ConnectToFileDB("PersistA_MVLOCKS", props);
            string scriptPath = testScriptPath + "TestSelfSchemaPersistA1.txt";
            TestUtil.testScript(sessionProxy1, scriptPath);
            sessionProxy1.close();

            Thread.Sleep(1000);

            SessionInterface sessionProxy2 = ConnectToFileDB("PersistA_MVLOCKS", props);
            scriptPath = testScriptPath + "TestSelfSchemaPersistA2.txt";
            TestUtil.testScript(sessionProxy2, scriptPath);
        }


        [TestMethod]
        public void TestSelfSchemaPersistB()
        {
            CleanUp("PersistB");
            SessionInterface sessionProxy1 = ConnectToFileDB("PersistB");
            string scriptPath = testScriptPath + "TestSelfSchemaPersistB1.txt";
            TestUtil.testScript(sessionProxy1, scriptPath);
            sessionProxy1.close();

            Thread.Sleep(1000);

            SessionInterface sessionProxy2 = ConnectToFileDB( "PersistB");
            scriptPath = testScriptPath + "TestSelfSchemaPersistB2.txt";
            TestUtil.testScript(sessionProxy2, scriptPath);
        }

        [TestMethod]
        public void TestSelfSchemaPersistC()
        {
            CleanUp("PersistC");
            SessionInterface sessionProxy1 = ConnectToFileDB("PersistC");
            string scriptPath = testScriptPath + "TestSelfSchemaPersistC1.txt";
            TestUtil.testScript(sessionProxy1, scriptPath);
            sessionProxy1.close();

            Thread.Sleep(1000);

            SessionInterface sessionProxy2 = ConnectToFileDB("PersistC");
            scriptPath = testScriptPath + "TestSelfSchemaPersistC2.txt";
            TestUtil.testScript(sessionProxy2, scriptPath);
        }

        [TestMethod]
        public void TestSelfSchemaPersistD()
        {
            CleanUp("PersistD");
            SessionInterface sessionProxy1 = ConnectToFileDB("PersistD");
            string scriptPath = testScriptPath + "TestSelfSchemaPersistD1.txt";
            TestUtil.testScript(sessionProxy1, scriptPath);
            sessionProxy1.close();

            Thread.Sleep(1000);

            SessionInterface sessionProxy2 = ConnectToFileDB("PersistD");
            scriptPath = testScriptPath + "TestSelfSchemaPersistD2.txt";
            TestUtil.testScript(sessionProxy2, scriptPath);
        }

        [TestMethod]
        public void TestSelfSchemaPersistE()
        {
            CleanUp("PersistE");
            SessionInterface sessionProxy1 = ConnectToFileDB("PersistE");
            string scriptPath = testScriptPath + "TestSelfSchemaPersistE1.txt";
            TestUtil.testScript(sessionProxy1, scriptPath);
            sessionProxy1.close();

            Thread.Sleep(1000);

            SessionInterface sessionProxy2 = ConnectToFileDB("PersistE");
            scriptPath = testScriptPath + "TestSelfSchemaPersistE2.txt";
            TestUtil.testScript(sessionProxy2, scriptPath);
        }

        [TestMethod]
        public void TestSelfImmediateShutdown()
        {
            CleanUp("TestSelfImmediateShutdown");
            SessionInterface sessionProxy1 = ConnectToFileDB("TestSelfImmediateShutdown");
            string scriptPath = testScriptPath + "TestSelfImmediateShutdown.txt";
            TestUtil.testScript(sessionProxy1, scriptPath);
            sessionProxy1.close();

            Thread.Sleep(1000);

            SessionInterface sessionProxy2 = ConnectToFileDB("TestSelfImmediateShutdown");
            scriptPath = testScriptPath + "TestSelfImmediateShutdownRecover.txt";
            TestUtil.testScript(sessionProxy2, scriptPath);
        }

        [TestMethod]
        public void TestSelfSeqRights()
        {
            CleanUp("SeqRights");
            SessionInterface sessionProxy1 = ConnectToFileDB("SeqRights");
            string scriptPath = testScriptPath + "TestSelfSeqRightsA.txt";
            TestUtil.testScript(sessionProxy1, scriptPath);
            sessionProxy1.close();

            Thread.Sleep(1000);

            SessionInterface sessionProxy2 = ConnectToFileDB("SeqRights");
            scriptPath = testScriptPath + "TestSelfSeqRightsB.txt";
            TestUtil.testScript(sessionProxy2, scriptPath);

            Thread.Sleep(1000);

            SessionInterface sessionProxy3 = ConnectToFileDB("SeqRights");
            scriptPath = testScriptPath + "TestSelfSeqRightsC.txt";
            TestUtil.testScript(sessionProxy3, scriptPath);
        }

        [TestMethod]
        public void TestSelfPersSchem()
        {
            CleanUp("PersSchem");
            SessionInterface sessionProxy1 = ConnectToFileDB("PersSchem");
            string scriptPath = testScriptPath + "TestSelfPersSchemA.txt";
            TestUtil.testScript(sessionProxy1, scriptPath);
            sessionProxy1.close();

            Thread.Sleep(1000);

            SessionInterface sessionProxy2 = ConnectToFileDB("PersSchem");
            scriptPath = testScriptPath + "TestSelfPersSchemB.txt";
            TestUtil.testScript(sessionProxy2, scriptPath);

            Thread.Sleep(1000);

            SessionInterface sessionProxy3 = ConnectToFileDB("PersSchem");
            scriptPath = testScriptPath + "TestSelfPersSchemC.txt";
            TestUtil.testScript(sessionProxy3, scriptPath);

            Thread.Sleep(1000);

            SessionInterface sessionProxy4 = ConnectToFileDB("PersSchem");
            scriptPath = testScriptPath + "TestSelfPersSchemD.txt";
            TestUtil.testScript(sessionProxy4, scriptPath);
        }


        [TestMethod]
        public void TestSelfSchemaPersistCrypto()
        {
            CleanUp("PersistCrypto");
            EffiProzProperties props2 = new EffiProzProperties();
            string cryptoType = "Rijndael";
            byte[] cryptoKeyBytes = Crypto.getNewKey(cryptoType);
            string cryptoKey = BitConverter.ToString(cryptoKeyBytes).Replace("-","");
            byte[] cryptoIvBytes = Crypto.getNewIv(cryptoType);
            string cryptoIv = BitConverter.ToString(cryptoIvBytes).Replace("-", "");
            props2.setProperty(EffiProzDatabaseProperties.url_crypt_key, cryptoKey);
            props2.setProperty(EffiProzDatabaseProperties.url_crypt_iv, cryptoIv);
            props2.setProperty(EffiProzDatabaseProperties.url_crypt_type, cryptoType);

            SessionInterface sessionProxy1 = ConnectToFileDB("PersistCrypto", props2);
         
            string scriptPath = testScriptPath + "TestSelfSchemaPersistE1.txt";
            TestUtil.testScript(sessionProxy1, scriptPath);
            sessionProxy1.close();

            Thread.Sleep(1000);

            SessionInterface sessionProxy2 = ConnectToFileDB("PersistCrypto", props2);
            scriptPath = testScriptPath + "TestSelfSchemaPersistE2.txt";
            TestUtil.testScript(sessionProxy2, scriptPath);
            sessionProxy2.close();
        }


        [TestMethod]
        public void TestSelfSchemaPersistCTblTest()
        {
            CleanUp("CTblTest");
            SessionInterface sessionProxy1 = ConnectToFileDB("CTblTest");
            string scriptPath = testScriptPath + "TestSelfSchemaPerCachTbl1.txt";
            TestUtil.testScript(sessionProxy1, scriptPath);
            sessionProxy1.close();

            Thread.Sleep(1000);

            SessionInterface sessionProxy2 = ConnectToFileDB("CTblTest");
            scriptPath = testScriptPath + "TestSelfSchemaPerCachTbl2.txt";
            TestUtil.testScript(sessionProxy2, scriptPath);
        }

        [TestMethod]
        public void TestSelfTempTable1()
        {
            CleanUp("TempTable");
            SessionInterface sessionProxy1 = ConnectToFileDB("TempTable1");
            string scriptPath = testScriptPath + "TestSelfTempTable1.txt";
            TestUtil.testScript(sessionProxy1, scriptPath);
            sessionProxy1.close();

            Thread.Sleep(1000);

            SessionInterface sessionProxy2 = ConnectToFileDB("TempTable1");
            scriptPath = testScriptPath + "TestSelfTempTable2.txt";
            TestUtil.testScript(sessionProxy2, scriptPath);
        }

        [TestMethod]
        public void TestText01()
        {
            CleanUp("TestText01");
            SessionInterface sessionProxy1 = ConnectToFileDB("TestText01");
            string scriptPath = testScriptPath + "TestText01.txt";
            TestUtil.testScript(sessionProxy1, scriptPath);
            sessionProxy1.close();

            Thread.Sleep(1000);

            SessionInterface sessionProxy2 = ConnectToFileDB("TestText01");
            scriptPath = testScriptPath + "TestText02.txt";
            TestUtil.testScript(sessionProxy2, scriptPath);
        }

        [TestMethod]
        public void TestCascade()
        {
            CleanUp("TestCascade");
            SessionInterface sessionProxy = ConnectToFileDB("TestCascade");
            string scriptPath = testScriptPath + "TestCascade1.txt";
            TestUtil.testScript(sessionProxy, scriptPath);
            sessionProxy.close();

            Thread.Sleep(1000);

            SessionInterface sessionProxy2 = ConnectToFileDB("TestCascade");
            scriptPath = testScriptPath + "TestCascade2.txt";
            TestUtil.testScript(sessionProxy2, scriptPath);
            sessionProxy.close();
        }

        [TestMethod]
        public void TestDbBackup()
        {
            CleanUp("TestDbBackup");
            //try
            //{
            //    File.Delete(dataPath + "TestDbBackup" + "\\online.tar");
            //}
            //catch (Exception) { }

            SessionInterface sessionProxy = ConnectToFileDB("TestDbBackup");
            string scriptPath = testScriptPath + "TestDbBackup1.txt";
            TestUtil.testScript(sessionProxy, scriptPath);
            sessionProxy.close();

            Thread.Sleep(1000);

            SessionInterface sessionProxy2 = ConnectToFileDB("TestDbBackup");
            scriptPath = testScriptPath + "TestDbBackup2.txt";
            TestUtil.testScript(sessionProxy2, scriptPath);
            sessionProxy.close();

            Thread.Sleep(100);

            using (FileStream unarchFile = File.OpenRead(dataPath + "TestDbBackup\\online.tar"))
            {
                EffiProz.Core.Lib.Tar.TarReader reader = new EffiProz.Core.Lib.Tar.TarReader(unarchFile);
                reader.ReadToEnd(dataPath + "TestDbBackup\\restore");
            }

            SessionInterface sessionProxy3 = ConnectToFileDB("TestDbBackup\\restore\\");
            scriptPath = testScriptPath + "TestDbBackup3.txt";
            TestUtil.testScript(sessionProxy3, scriptPath);

        }

    }
}
